﻿using System;
using System.Runtime.CompilerServices;

namespace CGF
{
    public struct CTaskMethodBuilder
    {
        CTask task;

        public CTask Task => task;

        public static CTaskMethodBuilder Create()
        {
            return new CTaskMethodBuilder() { task = CTask.Create() };
        }

        public void SetResult()
        {
            task.SetResult();
        }

        public void SetStateMachine(IAsyncStateMachine stateMachine) { }

        public void SetException(Exception exception)
        {
            Debug.LogError(exception);
        }

        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
        {
            awaiter.OnCompleted(stateMachine.MoveNext);
        }

        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
        {
            awaiter.OnCompleted(stateMachine.MoveNext);
        }

        public void Start<T>(ref T stateMachine) where T : IAsyncStateMachine
        {
            stateMachine.MoveNext();
        }
    }

    public struct CTaskMethodBuilder<T>
    {
        CTask<T> task;

        public CTask<T> Task => task;

        public static CTaskMethodBuilder<T> Create()
        {
            return new CTaskMethodBuilder<T>() { task = CTask<T>.Create() };
        }

        public void SetResult(T t)
        {
            task.SetResult(t);
        }

        public void SetStateMachine(IAsyncStateMachine stateMachine) { }

        public void SetException(Exception exception)
        {
            Debug.LogError(exception);
        }

        public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
        {
            awaiter.OnCompleted(stateMachine.MoveNext);
        }

        public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
        {
            awaiter.OnCompleted(stateMachine.MoveNext);
        }

        public void Start<TT>(ref TT stateMachine) where TT : IAsyncStateMachine
        {
            stateMachine.MoveNext();
        }
    }
}
